/*
 * Copyright (c) 2011, 2012 Alexander Kluth <alexander.kluth@outlook.com>
 * 
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2, or (at your option) any
 * later version.

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 */
package hardyhttp.filesystem;

import java.io.*;

/**
 * This class provides several method for filesystem-access.
 * 
 * @author Alexander Kluth
 */
public class Filesystem 
{
    String[] filenamesofdir;
    String htdocs;
    
    
    public Filesystem(String htdocs)
    {
        this.htdocs = htdocs;
    }
    
    
    public Filesystem()
    {
        
    }
    
    
    /**
     * Returns the absolute path of the file (on operating-system-level)
     * 
     * @param filePath relative path to the file
     * @return Absolute path
     */
    public String getFile(String filePath)
    {
        String file;
        
        file = getCwd();
        file += filePath; 
        
        return htdocs+filePath;
    }
    
    
    /**
     * Quite self-explanotory...checks, if the file is a dir 
     * 
     * @param file
     * @return true when directory, false otherwise
     */
    public boolean isDir(String file)
    {
        File filet = new File(file);
        return filet.isDirectory();
    }
    
    
    /**
     * Returns the current working directory...
     * Don't know if not search really or just not available in the JDK...
     * 
     * @return current working directory
     */
    public String getCwd()
    {        
        String tmppath = new File(".").getAbsolutePath().toString();
        String path = tmppath.substring(0, tmppath.length()-2);
        
        return path;
    }
    
    
    /**
     * Reads all contents of the requested file and returns it
     * 
     * @param filename
     * @return The contents of the file
     */
    public byte[] readFile(String filename)
    {
        FileInputStream fis;
        BufferedInputStream bis;
        File tmp = new File(filename);
        byte[] fileinput = new byte[(int)tmp.length()];
        
        try
        {
            fis = new FileInputStream(filename);
        }
        
        catch (FileNotFoundException fnfe)
        {
            return null;
        }
        
        bis = new BufferedInputStream(fis);
        
        try
        {
            bis.read(fileinput, 0, fileinput.length);
        }
        
        catch (IOException ioe)
        {
            return null;
        }

        return fileinput;
    }
    
    
    /**
     * Self-explanatory...check if file exist
     * 
     * @param filename
     * @return true if fle exist, false otherwise
     */
    public boolean fileExist(String filename)
    {
        File tmp = new File(filename);
        
        return tmp.exists();
    }
    
    
    /**
     * Even more self-explanotory...get the length of a file
     * 
     * @param filename
     * @return the length of the file
     */
    public long fileLength(String filename)
    {
        File tmp = new File(filename);
        
        return tmp.length();
    }
    
    
    /**
     * Get the actual size of the file in bytes
     * 
     * @param filename
     * @return Size in bytes
     */
    public int fileSize(String filename)
    {
        File f = new File(filename);
        return (int)f.length();
    }
    
    
    /**
     * Get the read-flag
     * 
     * @param filename
     * @return true if file can be read, false otherwise
     */
    public boolean canRead(String filename)
    {
        File f = new File(filename);
        return f.canRead();
    }
    
    
    /**
     * Get the write-flag
     * 
     * @param filename
     * @return true if file can be written, false otherwise
     */
    public boolean canWrite(String filename)
    {
        File f = new File(filename);
        return f.canWrite();
    }
    
    
    /**
     * Get the exec-flag
     * 
     * @param filename
     * @return true is file can be executed, false otherwise
     */
    public boolean canExec(String filename)
    {
        File f = new File(filename);
        return f.canExecute();
    }
    
    
    /**
     * Get the contents of a directory and return them
     * 
     * @return the contents of the directory as a string array, null otherwise
     **/
    public String[] getDirectoryContent(String dir)
    {
        File directory = new File(dir);
        
        if (directory.isDirectory())
            return directory.list();
        
        else
            return null;
    }
    
    
    /**
     * Build a path relative to the URI
     * 
     * @param files filenames
     * @param uri current uri
     * @param root indicates if we are in the root dir or not
     * @return the new array
     */
    public String[] getDirectoryContentRelative(String[] files, String uri, boolean root)
    {
        String[] myfiles = new String[files.length];
        String str = "";
        
        int i = 0;
        
        for (String file : files)
        {
            str += uri;
            
            if (root == false)
                str += "/";
            
            str += file;
            myfiles[i] = str;
            str = "";
            i++;
        }
        
        return myfiles;
    }
    
    
    /**
     * Removes the path from the file
     * 
     * @param reqfile
     * @return The file as a string
     */
    public String preperateReqfile(String reqfile)
    {
        StringBuilder tmp = new StringBuilder(reqfile);

        String cwd = getCwd();
        
        tmp = tmp.delete(0, cwd.length());
        
        return tmp.toString();
    }
    
    
    /**
     * Searchs for a index.htm{l} file in a directory.
     * Functionallity: open the directory, read the filenames to an array
     * and iterate through the hole array and compare the filenames
     * with index.htm{l}...quite lame I guess.
     * 
     * @param dir
     * @return the name of the index file if found, null otherwise
     **/
    public String searchForIndexFile(String dir)
    {
        filenamesofdir = getDirectoryContent(dir);
        
        for (int i = 0; i < filenamesofdir.length; i++)
        {
            //FIXME Hm...okay, quite lame and slow probably...using a sortingalgorithm maybe?
            if (filenamesofdir[i].equals("index.html") || filenamesofdir[i].equals("index.htm"))
            {
                return filenamesofdir[i];
            }
        }
        
        return null;
    }
}
